package com.gitee.huanminabc.utils_tools.file_tool.excel;

import com.gitee.huanminabc.jcommon.exception.BizException;
import com.gitee.huanminabc.utils_tools.file_tool.annotation.Mapping;
import com.gitee.huanminabc.utils_tools.file_tool.annotation.ExcelField;
import org.apache.poi.ss.usermodel.*;
import org.jsoup.helper.StringUtil;

import java.io.InputStream;
import java.lang.reflect.Field;
import java.util.*;

/**
 * //读取excel工具类 , 需要使用ExcelField注解,然后实体类必须全部是String类型, 后期自己转换
 * @author huanmin
 * @date 2024/1/16
 */
public class ReadExcelUtil {

    //读取exel,返回list
    public static  <T> List<T> readExcel(InputStream inputStream, Class<T> clazz) {
        List<T> list = new ArrayList<>();
        try {
            Workbook workbook = WorkbookFactory.create(inputStream);
            Sheet sheet = workbook.getSheetAt(0);
            Map<Integer, Field> fieldIntegerMap = readHead(0, sheet, clazz);
            int lastRowNum = sheet.getLastRowNum();
            for (int i = 1; i <=lastRowNum; i++) {
                Row row = sheet.getRow(i);
                if (row == null) {
                    continue;
                }
                T o = rowData(row,fieldIntegerMap, clazz);
                list.add(o);
            }

            workbook.close();
        } catch (Exception e) {
            throw new BizException(e,"ReadExcelUtil::readExcel-读取失败:{}", e.getMessage());
        }
        return list;
    }

    //找出需要处理的列 (从0开始)  逗号分割
    public static <T> Map<Integer,Field> readHead(int index, Sheet sheet, Class<T> clazz){
        Map<Integer,Field> result = new HashMap<>();
        Row row = sheet.getRow(index);

        Field[] fields = clazz.getDeclaredFields();
        Map<String,Field> fieldFilter = new HashMap<>();
        //找到需要处理的字段
        for (int i = 0; i < fields.length; i++) {
            fields[i].setAccessible(true);
            ExcelField annotation =  fields[i].getAnnotation(ExcelField.class);
            if (annotation != null&&annotation.value()!=null&&!annotation.value().trim().isEmpty()) {
                //检测字段类型是否是字符串
                if(!"java.lang.String".equals( fields[i].getType().getName())){
                    throw new BizException("ReadExcelUtil::readHead->格式错误{}->{}成员变量的类型不是字符串", clazz.getName(), fields[i].getName());
                }
                fieldFilter.put(annotation.value(),fields[i]);
            }

        }
        //遍历所有成员,找到需要处理的列
        short lastCellNum = row.getLastCellNum();
        for (int i = 0; i <lastCellNum; i++) {
            String stringCellValue = getCellValue(row,i);
            if(StringUtil.isBlank(stringCellValue)){
                continue;
            }
            String cellStr = stringCellValue.trim();
            Field field = fieldFilter.get(cellStr);
            if (field == null){
                continue;
            }
            result.put(i,field);
        }
        return result;
    }

    public static  <T>  T rowData( Row row, Map< Integer,Field> fieldIntegerMap,Class<T> clazz ) throws InstantiationException, IllegalAccessException {
        T t = clazz.newInstance();
        for (Map.Entry< Integer,Field> fieldIntegerEntry : fieldIntegerMap.entrySet()) {
            Field field = fieldIntegerEntry.getValue();
            field.setAccessible(true);
            Integer cellIndex = fieldIntegerEntry.getKey();
            field.setAccessible(true);
            ExcelField annotation = field.getAnnotation(ExcelField.class);
            if (annotation == null||annotation.value()==null||annotation.value().trim().isEmpty()) {
                continue;
            }
            String stringCellValue =getCellValue(row,cellIndex).trim();
            if(stringCellValue.isEmpty()){ //如果是空的,那么取默认值
                String example = annotation.defaultValue();
                if(example.isEmpty()){//如果没有默认值,就跳过直接设置为空
                    field.set(t,stringCellValue);
                    continue;
                }
                stringCellValue = example;
            }
            //类型映射转换
            Mapping[] mappings = annotation.mapping();
            for (Mapping mapping : mappings) {
                if (mapping.value().equals(stringCellValue)) {
                    stringCellValue = mapping.target();
                    break ;
                }
            }
            field.set(t,stringCellValue);
        }
        return t;
    }

    public   static  String getCellValue(Row row, int idx) {
        Cell cell = row.getCell(idx);
        if (cell == null) {
            return "";
        }
        if (CellType.NUMERIC.equals(cell.getCellType()) && DateUtil.isCellDateFormatted(cell)) {
            // 如果单元格是日期格式,就转换成时间戳
            Date date = cell.getDateCellValue();
            return date.getTime() + "";
        }
        return new DataFormatter().formatCellValue(cell);
    }


}
